package cn.zk.solution.server;

import cn.zk.solution.protocol.MessageProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.SimpleChannelInboundHandler;

import java.nio.charset.StandardCharsets;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

/**
 * handler
 *
 * ChannelInboundHandlerAdapter 是 ChannelInboundHandlerAdapter的子类
 */
public class TcpServerHandler extends SimpleChannelInboundHandler<MessageProtocol> {
    // 测试一个通道使用一个协议包
    public static final ConcurrentHashMap<ChannelId, MessageProtocol> map = new ConcurrentHashMap<>();
    // 每个客户端的handler是独立的
    private int count;
    /**
     * 读取消息
     *
     * @param ctx
     * @param message
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MessageProtocol message) throws Exception {
        // 接收数据
        int len = message.getLen();
        byte[] content = message.getContent();
        System.out.println("---------开始---------");
        System.out.println("服务器收到信息如下:");
        System.out.println("长度:"+len);
        System.out.println("内容:"+new String(content,StandardCharsets.UTF_8));
        System.out.println("消息包数据量:"+(++this.count));
        System.out.println("channelId:"+ctx.channel().id());
        System.out.println("消息包对象:"+message.hashCode());
        message.setLen(0);
        message.setContent(null);
        System.out.println("---------完毕---------");
        System.out.println();
        System.out.println();
        System.out.println();

        // 回送数据
//        String send = UUID.randomUUID().toString();
//        int sendLen = send.getBytes().length;
//        byte[] sendContent = send.getBytes(StandardCharsets.UTF_8);
//        // 创建协议包
//        MessageProtocol sendProtocol = new MessageProtocol();
//        sendProtocol.setLen(sendLen);
//        sendProtocol.setContent(sendContent);
//        ctx.writeAndFlush(sendProtocol);
    }
    /**
     * channel 活跃
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("==>["+channel.remoteAddress()+"]"+" 已经上线！");
        map.put(channel.id(),new MessageProtocol());
        System.out.println("==>[活跃的管道]<==");
        for (ChannelId channelId : map.keySet()) {
            System.out.println(channelId);
        }
        System.out.println("==>[活跃的管道]<==");
    }

    /**
     * channel 不活跃
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        System.out.println("==>["+channel.remoteAddress()+"]"+" 已经下线！");
        map.remove(channel.id());
        System.out.println("==>[活跃的管道]<==");
        for (ChannelId channelId : map.keySet()) {
            System.out.println(channelId);
        }
        System.out.println("==>[活跃的管道]<==");
    }

    /**
     * 出现异常会触发该方法 -> 关闭channel
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        // 关闭
        ctx.close();
    }

}
